﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.Practices.CompositeUI.Properties;
using Microsoft.Practices.CompositeUI.Utility;

namespace Microsoft.Practices.CompositeUI.UIElements
{
    /// <summary>
    /// 	Catalog that keeps track of each <see cref = "IUIElementAdapterFactory" /> that is available.
    /// </summary>
    public class UIElementAdapterFactoryCatalog : IUIElementAdapterFactoryCatalog
    {
        #region Collection Fields & Properties

        private readonly List<IUIElementAdapterFactory> _factories = new List<IUIElementAdapterFactory>();

        #endregion

        #region Implementation of IUIElementAdapterFactoryCatalog

        /// <summary>
        /// 	Dictionary of the availble factories.
        /// </summary>
        public IList<IUIElementAdapterFactory> Factories
        {
            get
            {
                return _factories.AsReadOnly();
            }
        }

        /// <summary>
        /// 	Retrieves a factory for the given UI element.
        /// </summary>
        /// <param name = "uiElement">The UI element to lookup a factory for.</param>
        /// <returns>A factory to use to create <see cref = "IUIElementAdapter" /> for the UI element.</returns>
        public IUIElementAdapterFactory GetFactory(object uiElement)
        {
            foreach (var factory in _factories.Where(factory => factory.Supports(uiElement)))
            {
                return factory;
            }
            throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.NoRegisteredUIElementFactory, uiElement.GetType()));
        }

        /// <summary>
        /// 	Adds an entry in the factories dictionary.
        /// </summary>
        /// <param name = "factory">The factory to register with the catalog.</param>
        public void RegisterFactory(IUIElementAdapterFactory factory)
        {
            Guard.ArgumentNotNull(factory, "factory");
            _factories.Add(factory);
        }

        #endregion
    }
}